﻿using System;
using System.Collections;
using System.Collections.ObjectModel;
using System.ComponentModel.Composition;
using System.Windows.Input;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using VisualWip.Core;
using VisualWip.Core.Interfaces;
using VisualWip.PresentationModel;
using WorkItem = VisualWip.Core.WorkItem;

namespace VisualWip.TFS2010Providers
{
    [Export(typeof (IWorkItemProvider))]
    public class TfsWorkItemWorkProvider : IWorkItemProvider, IWorkItemBehaviorToCommandProvider
    {
        private const string TFSProjectNameKey = "project";
        private const string TFSMeKey = "me";
        public const string ProviderName = "Tfs2010WorkItemWorkProvider";

        public TfsWorkItemWorkProvider()
        {
            QueryContext = new Hashtable();
            Connection = new TfsConnection();
        }

        public TfsConnection Connection { get; protected set; }
        public Hashtable QueryContext { get; protected set; }

        public WorkItemStore WorkItemStore
        {
            get
            {
                CheckForConnection();
                return Connection.WorkItemStore;
            }
        }

        public Project TeamProject
        {
            get
            {
                CheckForConnection();
                return Connection.TeamProject;
            }
        }

        #region IWorkItemBehaviorToCommandProvider Members

        public ICommand GetCommand(IWorkItemBehavior workItemBehavior)
        {
            var openWorkItemBehavior = workItemBehavior as OpenWorkItemBehavior;
            if (openWorkItemBehavior != null)
                return new RelayCommand(param => OpenWorkItem(openWorkItemBehavior.WorkItem));

            return new RelayCommand(param => { }, param => false);
        }

        #endregion

        #region IWorkItemProvider Members

        public void Connect()
        {
            if (Connection.IsConnected)
                return;

            Connection.Connect();

            if (Connection.IsConnected)
            {
                if (QueryContext.ContainsKey(TFSProjectNameKey))
                    QueryContext.Remove(TFSProjectNameKey);
                QueryContext.Add(TFSProjectNameKey, Connection.TeamProject.Name);

                if (QueryContext.ContainsKey(TFSMeKey))
                    QueryContext.Remove(TFSMeKey);
                QueryContext.Add(TFSMeKey, Connection.ConnectedAs);
            }
        }


        public string Name
        {
            get { return ProviderName; }
        }

        public void Init()
        {
            Connect();
        }

        public bool IsConnected
        {
            get { return Connection.IsConnected; }
        }

        public Collection<WorkItem> GetWork(IQuery query)
        {
            var queryBase = query as WorkItemQueryBase;
            if (queryBase != null)
                return queryBase.GetWork(this);

            return new Collection<WorkItem>();
        }

        public int GetWorkCount(IQuery query)
        {
            var queryBase = query as WorkItemQueryBase;
            if (queryBase != null)
                return queryBase.GetWorkCount(this);

            return 0;
        }

        public WorkItem GetWorkItem(string id)
        {
            int workItemId;
            if (int.TryParse(id, out workItemId))
            {
                try
                {
                    Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem workItem =
                        WorkItemStore.GetWorkItem(workItemId);
                    return WorkItemTransformer.TransformWorkItem(workItem);
                }
                catch (Exception e)
                {
                    return new ErrorWorkItem(e);
                }
            }

            return new ErrorWorkItem("The Id has to be an integer",
                                     string.Format("The provided work item id: {0} has to be an integer", id));
        }

        #endregion

        private void CheckForConnection()
        {
            if (!IsConnected)
                Connect();
            if (!IsConnected)
                throw new NoWorkItemProviderConnectionException("Could not connect to Team Foundation Server");
        }

        public void OpenWorkItem(WorkItem workItem)
        {
            Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem wi =
                WorkItemStore.GetWorkItem(int.Parse(workItem.Id));
            //var form = new WorkItemEditor(wi);
            //form.ShowDialog();
        }
    }
}